package com.zhu;

import com.zhu.classfile.ClassBinary;
import com.zhu.classpath.ClassPathManager;
import com.zhu.cmd.Cmd;
import com.zhu.utils.ClassDataUtil;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import static com.zhu.utils.ClassDataUtil.readAllBytes;

//JVM模拟程序的主类
public class JvmByJavaMain {
    //JVM模拟程序的主函数
    //javac -d D:\computerBookCode\jvmByJava\out -encoding UTF-8 D:\computerBookCode\jvmByJava\src\main\java\com\zhu\*.java
    //编译第一步
    public static void main(String[] args) throws IOException {
        String[] args1 = {
                "-Xjre", "D:\\java8_21\\jdk8u66\\jre",
                "-cp",  "D:\\computerBookCode\\jvmByJava\\target\\classes",
                "com.zhu.classfile.ClassBinary",
                "arg1", "arg2"
        };
        Cmd cmd = Cmd.parseCmd(args1);
        if (cmd.getVersionFlag()){
            System.out.println("jvmByJava version is 1");
        }else if (cmd.getHelpFlag() || "".equals(cmd.getMainClassName())){
            Cmd.printUsage();
        }else {
            startJvm(cmd);
        }
    }

    public static void startJvm(Cmd cmd) throws IOException {
        System.out.println("helpFlag:"+cmd.getHelpFlag());
        System.out.println("versionFlag:"+cmd.getVersionFlag());
        System.out.println("classPath:"+cmd.getClassPath());
        System.out.println("mainClassName:"+cmd.getMainClassName());
        System.out.println("args:"+java.util.Arrays.toString(cmd.getArgs()));
        ClassPathManager classPathManager = ClassPathManager.createClassPathManager(cmd.getJrePath(), cmd.getClassPath());
        // 把点号替换成斜杠 java com.example.MyApp
        //com.example.MyApp   →   com/example/MyApp
        //       .                     /
        String className = cmd.getMainClassName().replace(".", "/");
        InputStream inputStream = classPathManager.readClass(className);
        byte[] classBytes = ClassDataUtil.readAllBytes(inputStream);
        ClassBinary classBinary = ClassBinary.parseClassDataToClassBinary(classBytes);

        // 打印十六进制，每行16字节
        printHex(classBytes);
    }



    // 打印 byte[] 为十六进制，每行16字节
    public static void printHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            // 每16个字节换行
            if (i % 16 == 0) {
                if (i > 0) sb.append('\n');
                sb.append(String.format("%06X: ", i)); // 地址偏移，如 000000:
            }
            sb.append(String.format("%02X ", bytes[i])); // 每个字节如 CA
        }
        // 如果最后一行不满16个，也换行
        if (bytes.length > 0) sb.append('\n');
        System.out.println(sb.toString());
    }

}